package a_sorting_basic.c_insertion_sort.sorting_helper;

import utils.ArrayGeneric;

import java.util.Random;

@SuppressWarnings("unchecked")
public abstract class SortingHelperC {

    public void testSorting(String desc, int numbers) {
        System.out.print(desc + " on " + numbers + " integer numbers");
        ArrayGeneric arr = initSorting(numbers);
        long startTime = System.nanoTime();
        executeSorting(arr);
        long endTime = System.nanoTime();
        assert testSorted(arr);
        double duration = (endTime - startTime) / 1000000000.0;
        System.out.println("\t\tduration -> " + duration + "s");
    }

    public void testNearlySorting(String desc, int numbers, int swapTimes) {
        System.out.print(desc + " on nearly ordered " + numbers + " integer numbers with swap times " + swapTimes);
        ArrayGeneric arr = initSorting(numbers, swapTimes);
        long startTime = System.nanoTime();
        executeSorting(arr);
        long endTime = System.nanoTime();
        assert testSorted(arr);
        double duration = (endTime - startTime) / 1000000000.0;
        System.out.println("\t\tduration -> " + duration + "s");
    }

    private boolean testSorted(ArrayGeneric arr) {
        for (int i = 0; i < arr.length() - 1; i++) {
            if (arr.get(i + 1).compareTo(arr.get(i)) < 0) {
                return false;
            }
        }
        return true;
    }

    public  ArrayGeneric initSorting(int numbers) {
        return getRandomIntegerArray(numbers,0,10000);
    }
    public  ArrayGeneric initSorting(int numbers, int swapTimes){
        return getNearlySortedIntegerArray(numbers, swapTimes);
    }

    public abstract void executeSorting(ArrayGeneric array);

    // 生成一个近似排序的数组
    public static ArrayGeneric getNearlySortedIntegerArray(int size, int swapTimes) {
        ArrayGeneric<Integer> array = new ArrayGeneric<>(size);
        for (int i = 0; i < size; i++) {
            array.put(i, i);
        }
        Random rand = new Random();
        for (int i = 0; i < swapTimes; i++) {
            int m = rand.nextInt(size);
            int n = rand.nextInt(size);
            array.swap(m, n);
        }
        return array;
    }

    // 随机生成一个整数数组
    public static ArrayGeneric<Integer> getRandomIntegerArray(int size, int min, int max) {
        ArrayGeneric<Integer> array = new ArrayGeneric<>(size);
        Random rand = new Random(System.currentTimeMillis());
        for (int i = 0; i < array.length(); i++) {
            array.put(i, rand.nextInt(max - min + 1) + min);
        }
        return array;
    }
}
